package org.jeecg.modules.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.jeecg.common.aspect.annotation.AutoRecordLog;
import org.jeecg.common.util.BeanPlusUtil;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.modules.system.entity.SysDataLog;
import org.jeecg.modules.system.mapper.SysDataLogMapper;
import org.jeecg.modules.system.service.ISysDataLogService;
import org.jeecg.modules.system.vo.SysDataLogVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * @Description: 系统数据日志实现类
 * @author: jeecg-boot
 */
@Service
public class SysDataLogServiceImpl extends ServiceImpl<SysDataLogMapper,SysDataLog> implements ISysDataLogService {
	@Autowired
	private SysDataLogMapper logMapper;

	@Autowired
	private RedisUtil redisUtil;
	/**
	 * 添加数据日志
	 */
	@Override
	public void addDataLog(String tableName, String dataId, String dataContent) {
		String versionNumber = "0";
		String dataVersion = logMapper.queryMaxDataVer(tableName, dataId);
		if(dataVersion != null ) {
			versionNumber = String.valueOf(Integer.parseInt(dataVersion)+1);
		}
		SysDataLog log = new SysDataLog();
		log.setDataTable(tableName);
		log.setDataId(dataId);
		log.setDataContent(dataContent);
		log.setDataVersion(versionNumber);
		this.save(log);
	}

	@Override
	public void loadChildData(IPage<SysDataLog> iPage,String table) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		List<SysDataLog> records = iPage.getRecords();
		Object o = redisUtil.get(table);
		Map map0 = BeanUtil.toBean(o, Map.class);
		Class<?> clazz = Class.forName(map0.get("clazz").toString());
//		Object obj = clazz.newInstance();
		if(!clazz.isAnnotationPresent(AutoRecordLog.class) || !clazz.getAnnotation(AutoRecordLog.class).existParent()){
			return;
		}
		List<SysDataLog> record = iPage.getRecords();
		for (SysDataLog sysDataLog : record) {
			StringBuilder stringBuilder = new StringBuilder();
			String dataId = sysDataLog.getDataId();
			String tableDes = sysDataLog.getTableDes();
			if(!StrUtil.isEmpty(sysDataLog.getDataContent())){
				stringBuilder.append(tableDes+":").append(sysDataLog.getDataContent());
			}
			List<SysDataLog> chlidList = this.list(new LambdaQueryWrapper<SysDataLog>().eq(SysDataLog::getParentTable, table)
					.eq(SysDataLog::getParentId, dataId));
			if(!CollectionUtils.isEmpty(chlidList)){
				stringBuilder.append(chlidList.get(0).getTableDes()+":");
				for (SysDataLog chlidLog : chlidList) {
					stringBuilder.append(chlidLog.getDataContent());
				}
			}
			sysDataLog.setDataContent(stringBuilder.toString());
		}

	}

	/**
	 * 获取数据变动日志
	 * @param dataTable
	 * @param dataId
	 * @return
	 */
	@Override
	public List<SysDataLogVo> loglist(String dataTable, String dataId) {
		List<SysDataLog> list = this.list(new LambdaQueryWrapper<SysDataLog>().eq(SysDataLog::getDataTable, dataTable)
				.eq(SysDataLog::getDataId, dataId).orderByDesc(SysDataLog::getLogtime,SysDataLog::getCreateTime));
		List<SysDataLogVo> voList = BeanPlusUtil.toBeanList(list, SysDataLogVo.class);
		voList.forEach((obj)->{
			if(StrUtil.isEmpty(obj.getDataContent()) && obj.getType().equals("insert")){
				obj.setDataContent("新增");
			}
			this.formatDataContent(obj);
			obj.setDataContent(obj.getDataContent().replace("{", "").replace("}", ""));
			// 查询子数据
			List<SysDataLog> chlidList = this.list(new LambdaQueryWrapper<SysDataLog>().eq(SysDataLog::getParentTable, dataTable)
					.eq(SysDataLog::getParentId, dataId).eq(SysDataLog::getParentLogtime, obj.getLogtime())
					.orderByDesc(SysDataLog::getLogtime ));
			List<SysDataLog> sysDataLogs = this.distinctData(chlidList);
			obj.setChildlist(sysDataLogs);
		});
		return voList;
	}

	/**
	 * 剔除无用数据
	 * @param chlidList
	 * @return
	 */
	private List<SysDataLog> distinctData(List<SysDataLog> chlidList ){
		if(CollectionUtils.isEmpty(chlidList)){
			return null;
		}
		Map<String,Integer> map = new HashMap<>();
		List<Integer> indexList = new ArrayList<>();
		List<SysDataLog> copyList = ObjectUtil.cloneByStream(chlidList);
		for (int i = 0; i < chlidList.size(); i++) {
			SysDataLog sysDataLog = chlidList.get(i);
			String dataId = sysDataLog.getDataId();
			String type = sysDataLog.getType();
			if(type.equals("delete")){
				map.put(dataId,i);
			}else {
				if(map.containsKey(dataId)){
					Integer index = map.get(dataId);
					indexList.add(index);
//					copyList.remove(index.intValue());
				}
			}
		}
		Collections.sort(indexList, Collections.reverseOrder());
		for (Integer integer : indexList) {
			copyList.remove(integer.intValue());
		}

		copyList.forEach(item->{
			item.setDataContent(item.getDataContent().replace("{", "").replace("}", ""));
		});

		return copyList;
	}

	/**
	 * 格式话数据
	 * @param vo
	 */
	public void formatDataContent(SysDataLogVo vo){
		String dataContent = vo.getDataContent();
		Map map = BeanPlusUtil.toBean(dataContent, Map.class);
		Set set = map.keySet();
		if(set.size() == 1){
			Iterator iterator = set.iterator();
			while (iterator.hasNext()){
				String key = (String) iterator.next();
				if(key.equals("更新日期")){
					vo.setDataContent("");
				}
			}
		}
	}


}
